import { defineStore } from 'pinia'
import { ref } from 'vue'
import { agencyAsync } from '@/appox/appox'
import { appoxUtility } from '@/appox/appox'
import { AppoxBusMessageSample } from '@/appox/appox'

const STORAGE_KEY = 'AppoxJsTest.BusTracerChannelFilter'
const MAX_SELECTED_ITEMS = 2

export const useBusTracerStore = defineStore('busTracer', () => {
  // 状态
  const busData = ref([])
  const busDataMap = ref({}) // 用于通过orderID快速索引
  const selectedItems = ref([]) // 用于存储选中的项目队列
  
  // 从 localStorage 读取 channelStates，如果不存在则使用默认值
  const defaultChannelStates = Array(48).fill(false).map((_, i) => i < 4) // 默认CH1~CH4开启
  const storedStates = localStorage.getItem(STORAGE_KEY)
  const channelStates = ref(storedStates ? JSON.parse(storedStates) : defaultChannelStates)

  // 动作
  function addBusData(orderID, type, channel, localID, sample) {
    // 检查是否已存在该orderID
    if (orderID in busDataMap.value) {
      // 如果存在，将sample添加到sampleBuffer中
      busDataMap.value[orderID].sampleBuffer.push(sample)
      return
    }

    const newItem = {
      orderID,
      type,
      channel,
      localID,
      time: null,
      fps: null,
      protocol: null,
      messageName: null,
      sampleBuffer: [sample],
      isUpdating: false,
      gotMessageInfo: false,
      lastUpdateFpsTime: null,
      showDetails: false,
      details: []
    }

    // 更新索引
    busDataMap.value[orderID] = newItem

    // 找到合适的插入位置
    const insertIndex = busData.value.findIndex(item => item.orderID > orderID)
    if (insertIndex === -1) {
      // 如果没有找到更大的orderID，则添加到末尾
      busData.value.push(newItem)
    } else {
      // 在找到的位置插入
      busData.value.splice(insertIndex, 0, newItem)
    }
  }

  function toggleDetails(orderID) {
    const item = busDataMap.value[orderID]
    if (item) {
      if (!item.showDetails) {
        // 如果当前项目未选中，则添加到队列末尾
        selectedItems.value.push(orderID)
        item.showDetails = true
        
        // 如果队列超过最大长度，则取消第一个项目的选中状态
        if (selectedItems.value.length > MAX_SELECTED_ITEMS) {
          const firstOrderID = selectedItems.value.shift()
          const firstItem = busDataMap.value[firstOrderID]
          if (firstItem) {
            firstItem.showDetails = false
          }
        }
      } else {
        // 如果当前项目已选中，则从队列中移除
        const index = selectedItems.value.indexOf(orderID)
        if (index !== -1) {
          selectedItems.value.splice(index, 1)
        }
        item.showDetails = false
      }
    }
  }

  function clearAll() {
    busData.value = []
    busDataMap.value = {}
    selectedItems.value = [] // 清空选中队列
  }

  function toggleChannel(channelIndex) {
    channelStates.value[channelIndex] = !channelStates.value[channelIndex]
    // 保存到 localStorage
    localStorage.setItem(STORAGE_KEY, JSON.stringify(channelStates.value))
    if (channelStates.value[channelIndex]) {
      agencyAsync.addBusMessageReference(channelIndex + 1)
    } else {
      agencyAsync.removeBusMessageReference(channelIndex + 1)
    }
  }

  function onConnected() {
    // 为所有已选中的通道添加引用
    channelStates.value.forEach((isSelected, index) => {
      if (isSelected) {
        agencyAsync.addBusMessageReference(index + 1)
      }
    })
  }

  function onResetData() {
    clearAll()
  }

  function onInputData(data) {
    if (data instanceof AppoxBusMessageSample) {
      let orderID = data.channel * 4294967296 + data.id
      addBusData(orderID, data.type, data.channel, data.id, data)
    }
  }

  function updateFPS(item) {
    item.isUpdating = true;
    agencyAsync.getBusMessageFPS(item.channel, item.localID).then(fps => {
      if (fps != null && fps > 0) item.fps = fps
      item.lastUpdateFpsTime = Date.now()
      item.isUpdating = false
    })
  }

  function updateProtocol(item) {
    item.isUpdating = true;
    agencyAsync.getBusMessageInfoByLocalID(item.channel, item.localID).then(info => {
      if (info != null) {
        item.protocol = info.protocolFileID
        item.messageName = info.messageName
      }
      item.isUpdating = false
    })
  }

  // 格式化信号值显示
  function formatSignalValue(value) {
    if (typeof value !== 'number') return null
    
    // 如果是整数，直接返回
    if (Number.isInteger(value)) return value
    
    // 对于小数，保留8位有效数字
    return Math.abs(value) < 1 ? Number(value.toFixed(8)) : Number(value.toPrecision(8))
  }

  function updateDetails(item, interestSample) {

    if (interestSample == null) {
      item.details = []
      return;
    }

    item.isUpdating = true
    agencyAsync.parseBusMessage(interestSample).then(result => {
      item.details = []
      item.details.push({ key: 'State', value: interestSample.state })
      item.details.push({ key: 'Length', value: interestSample.length })
      let hexData = Array.from(interestSample.data).map(byte => byte.toString(16).toUpperCase().padStart(2, '0')).join(' ')
      item.details.push({ key: 'Data', value: hexData })
      if (result != null) {
        for (let signal of result) {
          let text = formatSignalValue(signal.value)
          if (signal.enumValue != null && signal.enumValue != '') text += ' (' + signal.enumValue + ')'
          if (signal.unit != null && signal.unit != '') text += ' [' + signal.unit + ']'
          item.details.push({ key: signal.signalName, value: text })
        }
      }
      item.isUpdating = false
    })
  }

  function updateModel() {
    let interest = appoxUtility.getInterestTimeLocal()
    for (let orderID in busDataMap.value) {

      let item = busDataMap.value[orderID]
      let searchResult = appoxUtility.searchSample(item.sampleBuffer, interest, 1.0)
      let interestSample = null
      if (searchResult == null) {
        item.time = null
      }
      else {
        interestSample = searchResult.weight1 > searchResult.weight2 ? searchResult.sample1 : searchResult.sample2
        item.time = interestSample.timestamp.offset
      }

      if (!item.isUpdating) {
        if (item.protocol == null || item.messageName == null) {
          updateProtocol(item)
        }
        if (item.lastUpdateFpsTime == null || Date.now() - item.lastUpdateFpsTime > 1000) {
          item.lastUpdateFpsTime = Date.now()
          updateFPS(item)
        }
        if (item.showDetails) {
          updateDetails(item, interestSample)
        }
      }
    }
  }

  return {
    // 状态
    busData,
    busDataMap,
    channelStates,
    selectedItems,
    // 动作
    addBusData,
    toggleDetails,
    clearAll,
    toggleChannel,
    onConnected,
    onResetData,
    onInputData,
    updateModel,
  }
}) 